#pragma once

#include <deque>
#include "../vectormath.h"

namespace Tmpl {

class MapZoneTexture
{
public:
	MapZoneTexture(const char* filename);

	void SetSlope(float min, float max){mSlopeMin = min; mSlopeMax = max;}
	void SetHeight(float min, float max){mHeightMin = min; mHeightMax = max;}
	void SetFalloff(float slope, float height){mSlopeFalloff = slope; mHeightFalloff = height;}
	void SetDensity(float density){mDensity = density;}
	void SetTextureId(unsigned char id){mTexId = id;}

	const char* GetName() const {return mName;}
	unsigned char GetTextureId() const {return mTexId;}
	float GetSlopeMin() const {return mSlopeMin;}
	float GetSlopeMax() const {return mSlopeMax;}
	float GetHeightMin() const {return mHeightMin;}
	float GetHeightMax() const {return mHeightMax;}
	float GetSlopeFalloff() const {return mSlopeFalloff;}
	float GetHeightFalloff() const {return mHeightFalloff;}
	float GetDensity() const {return mDensity;}

private:
	const char* mName;
	unsigned char mTexId;
	float mDensity;
	float mSlopeMin, mSlopeMax;
	float mHeightMin, mHeightMax;
	float mSlopeFalloff, mHeightFalloff;
};

class MapZoneType
{
public:
	MapZoneType(float roughness, float mountains, float mountainFrequency=0.25f);

	void AddTexture(MapZoneTexture* tex){mTextures.push_back(tex);}
	int GetTextureCount()const{return (int)mTextures.size(); }
	MapZoneTexture* GetTexture(int idx)const{return mTextures[idx];}

	void SetRoughness(float roughness){mRoughness = roughness;}
	float GetRoughness()const{return mRoughness;}

	void SetMountains(float Mountains){mMountains = Mountains;}
	float GetMountains()const{return mMountains;}

	void SetMountainFrequency(float MountainFrequency){mMountainFrequency = MountainFrequency;}
	float GetMountainFrequency()const{return mMountainFrequency;}
private:
	std::deque<MapZoneTexture*> mTextures;
	float mRoughness;
	float mMountains;
	float mMountainFrequency;
};

struct MapZoneLink;
class MapZone
{
public:
	MapZone(MapZoneType* type, Vec2f pos);

	MapZoneType* GetType(){return mType;}
	Vec2f GetPos()const{return mPos;}

	void AddLink(MapZone* zone);
	void RemoveLink(MapZone* zone);

	MapZoneLink* GetLink(MapZone* zone) const;
	bool isLinked(MapZone* zone) const {return GetLink(zone) != 0;}
	int GetLinkCount() const {return (int)mLinks.size();}
private:
	short mId;
	Vec2f mPos;
	MapZoneType* mType;
	std::deque<MapZoneLink*> mLinks;
};

struct MapZoneLink
{
	MapZone* zone;
	float distance;
};

}; // namespace Tmpl